<div class="span-22 last options-holder">
	<?= $this->partial('_partial/common_head.phtml', array('controller' => 'constructor')) ?>
</div>

<hr class="bottom"/>

<style>
<!--
.form-block {
	padding:10px;
	margin-bottom:5px;
	border:1px solid silver;
}
.ui-droppable-acticve-class {
	border: 1px dashed #84b937;
}
.width-fluid {width: 99%;}
#forms-types .form-block {
	cursor: move;
}
#forms-constructor {margin: 0; padding: 0;}
#forms-constructor li {
	list-style: none;
	display: block;
	border: 1px solid #333;
	padding: 5px;
	margin-bottom: 5px;
}
-->
</style>
<?php
$this->headScript()
	->appendFile('js/jquery/jquery-1.2.6.pack.js')
//	->appendFile('js/jquery/jquery.livequery.min.js')
	->appendFile('js/jquery/ui/packed/ui.core.packed.js')
	->appendFile('js/jquery/ui/packed/ui.draggable.packed.js')
	->appendFile('js/jquery/ui/packed/ui.droppable.packed.js')
	->appendFile('js/jquery/ui/packed/ui.sortable.packed.js')
	->appendFile('js/jquery/ui/packed/ui.resizable.packed.js')
	->appendFile('js/jquery/ui/packed/ui.dialog.packed.js');
$this->headLink()
	->appendStylesheet('js/jquery/themes/jquery-ui-themeroller/jquery-ui-themeroller.css');	
?>

<script type="text/javascript">
<!--

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;
    var temp = new obj.constructor(); // changed (twice)
    for(var key in obj)
        temp[key] = clone(obj[key]);
    return temp;
}

function build_http_query(value, key){
	// nie interpretuje wogule array ..?? ale dziala
	if (null === value){
		return '&';
	} else
	if (true === value) {
		return 'true&';
	} else
	if (false === value) {
		return 'false&';
	} else
	if (typeof value === 'object') {
		var url = [];
		$.each(value, function(i,e){
			var k = key === undefined ? i :  key+'['+i+']';
			if (typeof e === 'object') {
				url.push(build_http_query(e, k));
			} else {
				url.push(k+'=' + build_http_query(e, k));
			}
		});
		return url.join('&');
	}
	if(value == undefined) {
		return null;
	} else {
		return value.toString();
	}
}

var WFormValidator = {
	name: null,

	validator: null,
	
	options: {},

	element: null,

	selected: false,
	
	toString: function() {
		return this.getElement();
	},

	reset: function() {
		this.name = null;
		this.validator = null;
		this.options = {};
		this.element = null;
	},

	initElement: function(element){
		return element;
	},
	
	getElement: function() {
		if (null == this.element) {
			this.element = $('<option/>');

			var self = this;
			
			this.element
				.val(this.validator)
				.text(this.name)
				.click(function() {
					self.handler(self);
				});

			if (this.getSelected()) {
				this.element.attr('selected','selected');
			}
			
			this.element = this.initElement(this.element);
		}
		return this.element;
	},

	toObject: function() {
		return {
			options: this.options,
			validator: this.validator
		};
	},

	handler: function(self) {
		alert('[EE] WFormValidator::handler, metoda nie zdefiniowana!');
	},

	getValidatorName: function() {
		return this.validator;
	},

	setOptions: function(options) {
		if (typeof options == 'object') {
			this.options = options;
		} else {
			console.log('WFormValidator::setOptions wrong type');
		}
	},

	setSelected: function(selected) {
		this.selected = selected;
	},

	getSelected: function(selected) {
		return this.selected;
	}
};

var GreaterThan = clone(WFormValidator);
GreaterThan.name = 'Liczba większa od ..';
GreaterThan.validator = 'GreaterThan';
GreaterThan.options = {min: null};
GreaterThan.initElement = function(element){
	if (this.options.min != null) {
		element.text(element.text() + '['+this.options.min+']');
	}
	return element;
};
GreaterThan.handler = function(self) {
	var value = prompt("Podaj wartość:");
	var element = this.getElement();
	if (null != value && '' != value) {
		value = parseInt(value);
		self.options.min = value;
		element.text(element.text().replace(/(\[\d*\])/,'') + '['+value+']');
	} else {
		self.options.min = null;
		element.text(element.text().replace(/(\[\d*\])/,''));
	}
}

var StringLength = clone(WFormValidator);
StringLength.name = 'Dł. tekstu ';
StringLength.validator = 'StringLength';
StringLength.options = {min: null,max: null};
StringLength.initElement = function(element){
	if (this.options.min != null) {
		element.text(element.text() + '['+this.options.min+','+this.options.max+']');
	}
	return element;
};
StringLength.handler = function(self) {
	var value = prompt("Podaj wartość minimalną (Anuluj nie ma):");
	var element = this.getElement();
	if (null != value && '' != value) {
		value = parseInt(value);
		self.options.min = value;
	} else {
		self.options.min = null;
	}

	var value = prompt("Podaj wartość maksymalną (Anuluj nie ma):");
	var element = this.getElement();
	if (null != value && '' != value) {
		value = parseInt(value);
		self.options.max = value;
	} else {
		self.options.max = null;
	}

	element.text(element.text().replace(/(\[.*\])/, ''));
	if (null != self.options.max || null != self.options.min) {
		element.text(element.text() + '['+this.options.min+','+this.options.max+']');
	}
}

var EmailAddress = clone(WFormValidator);
EmailAddress.name = 'Adres e-mail';
EmailAddress.validator = 'EmailAddress';
EmailAddress.handler = function(){};


var WFormElement = {
	type: 'text',
	name: null,
	options: {
		label: null,
		value: null,
		order: null,
		ignore: false,
		required: false,
		description: null,		
		validators: []
	},

	types: ['text','textarea','checkbox','radio','reset','submit'],
	validators: [GreaterThan,StringLength,EmailAddress],

	preview: null,
	
	element: null,

	reset: function() {
		this.type = 'text';
		this.name = null;
		this.options = {
			label: null,
			value: null,
			order: null,
			required: false,
			description: null,		
			validators: []
		};

		this.preview = null;
		
		this.element = null;
	},
	
	getElement: function() {
		if (null == this.element) {
			this.element =  $('<form>'+
									'<div class="span-4 element-preview">'+
									'</div>'+
									'<div class="span-4">'+
										'<label>Nazwa etykiety: <input type="text" name="label" class="width-fluid" /></label>'+
										'<label>Nazwa pola:     <input type="text" name="name"  class="width-fluid" /></label>'+
										'<label>Pole wymagane:  <input type="checkbox" name="required" value="true" class="width-fluid"/></label>'+
										'<label>Ignoruj pole:   <input type="checkbox" name="ignore" value="true" class="width-fluid"/></label>'+
									'</div>'+
									'<div class="span-4 ">'+
										'<label>Opis: <em>nie jest wymagany</em><br/> <input type="text" name="description" class="width-fluid" /></label>'+
										'<label>Wartość domyślna <em>nie jest wymagana</em><br/> <textarea name="value" class="width-fluid" style="height:30px;"></textarea></label>'+
									'</div>'+
									'<div class="span-4 last">'+
										'<label>Opcje walidacji: <em>nie są wymagane</em><br/> <select name="validators[]" class="width-fluid" multiple="multiple" size="5" /></label>'+
									'</div>'+
								'</form>'+
							'<div class="clear"></div>');

			
			this.element.find('[name=label]').val(this.getLabel());
			this.element.find('[name=name]').val(this.getName());
			this.element.find('[name=required]')[0].checked = this.getRequired();
			this.element.find('[name=ignore]')[0].checked = this.getIgnore();
			this.element.find('[name=description]').val(this.getDescription());
			this.element.find('[name=value]').val(this.getValue());

			var self = this;

//			console.log(this.options.validators);
//			$(this.options.validators,  function(i,val){
//				console.log(val);
//				var validator = self.setValidatorByName(val.validator);
//				validator.setOptions(val.options);
//				validator.setSelected(true);
//			});
			
			if (this.getPreview() != null) {
				this.element
					.find('.element-preview')
					.html(this.getPreview());
			}
		}
		return this.element;
	},
	
	toString: function() {
		var element = this.getElement();
		element = this.setupValidatorsForElement(element);
		element = this.initBindings(element);
		return element;
	},

	toObject: function() {
		var self = this;
		var validators = {};

		this.getElement().find('select :selected').each(function(i,val){
			var name = val.value;
			if (self.isValidatorByName(name)) {
				validators[name] = self.getValidatorByName(name).toObject();
			} else {
				console.log('no validator by position');
			}
		});

		this.options['validators'] = validators;
		
		return {
			type: this.type,
			name: this.name,
			options: this.options
		};
	},

	setupValidatorsForElement: function(element){
		var validatorEl = element.find('select');
		var validators  = this.getValidators();

		for(var i = 0; i < validators.length; i++) {
			validatorEl.append(validators[i].toString());
		}

		return element;
	},

	initBindings: function(element){
		var self = this;

		var nameEl = element.find('input[name=name]');
		var valueEl = element.find('textarea[name=value]');
		var labelEl = element.find('input[name=label]');
		var ignoreEl = element.find('input[name=ignore]');
		var requiredEl = element.find('input[name=required]');
		var descriptionEl = element.find('input[name=description]');
		
		nameEl.keyup(function(){
			var val = $(this).val();
			self.setName(val);
		});
		
		labelEl.keyup(function(){
			var val = $(this).val();
			self.setLabel(val);

			val = val.toLowerCase().replace(/([^\w+]+)/ig,'');
			nameEl.val(val);
			self.setName(val);
		});

		requiredEl.change(function(){
			if (this.checked) {
				self.setRequired(true);
			} else {
				self.setRequired(false);
			}
		});

		ignoreEl.change(function(){
			if (this.checked) {
				self.setIgnore(true);
			} else {
				self.setIgnore(false);
			}
		});

		descriptionEl.keyup(function(){
			var val = $(this).val();
			self.setDescription(val);
		});

		valueEl.keyup(function(){
			var val = $(this).val();
			self.setValue(val);
		});

		return element;
	},

	isTypeValid: function(type) {
		return (this.types.indexOf(type) == -1) ? false : true;
	},
	
	setType: function (type) {
		if(this.types.indexOf(type) == -1) {
			console.log('setType incorrect');
			return;
		}

		this.type = type;
	},

	setName: function (name) {
		this.name = name;
	},
	
	getName: function () {
		return this.name;
	},

	setValue: function (value) {
		this.options.value = value;
	},
	
	getValue: function () {
		return this.options.value;
	},

	setOrder: function (order) {
		this.options.order = order;
	},
	
	getOrder: function () {
		return this.options.order;
	},

	setLabel: function (label) {
		this.options.label = label;
	},
	
	getLabel: function () {
		return this.options.label;
	},

	setIgnore: function (ignore) {
		this.options.ignore = ignore;
	},
	
	getIgnore: function () {
		return this.options.ignore;
	},
	
	setRequired: function (required) {
		this.options.required = required;
	},
	
	getRequired: function () {
		return this.options.required;
	},

	setDescription: function (description) {
		this.options.description = description;
	},
	
	getDescription: function () {
		return this.options.description;
	},
	
	getValidators: function(){
		return this.validators;
	},

	setPreview: function(preview) {
		this.preview = preview;
	},

	getPreview: function() {
		return this.preview;
	},

	setOptions: function(options) {
		this.options = options;

		var self = this;
		
		if (typeof options.validators == 'object') {
			$.each(options.validators, function(i,v) {
				var validator = self.getValidatorByName(v.validator);
				if (typeof validator == 'object') {
					validator.setOptions(v.options);
					validator.setSelected(true);
				}
			});
		}
	},

	getOptions: function() {
		return this.options;
	},

	isValidatorByName: function(name) {
		for(var i = 0; i < this.validators.length; i++) {
			if (this.validators[i].getValidatorName() == name) {
				return true;
			}
		}
		return false;
	},
	
	getValidatorByName: function (name) {
		for(var i = 0; i < this.validators.length; i++) {
			if (this.validators[i].getValidatorName() == name) {
				return this.validators[i];
			}
		}
		return null;
	},

	setValidatorByName: function (name, validator) {
		for(var i = 0; i < this.validators.length; i++) {
			if (this.validators[i].getValidatorName() == name) {
				this.validators[i] = validator;
				return;
			}
		}
		this.validators.push(validator);
	}
};

var WFormManager = {
	elements: [],

	clear: function(){
		this.elements = [];
	},

	_order: [],

	setOrder: function(order) {
		this._order = order;
	},

	getOrder: function() {
		return this._order;
	},

	resetOrder: function() {
		this._order = null;
		this._order = [];
	},

	_orderAlgorithm: function(a,b) {
		// tak musi być bo uchwyt w [].sort(callback) nie odwoluje się do this..
		
		var elements = WFormManager.getElements();
		var positionA = elements.indexOf(a);
		var positionB = elements.indexOf(b);

		if (positionB == -1) {
			return 1;
		} else 
		if (positionA == -1){
			return -1;
		}

		// w [].indexOf(positionA) wartosc elemntu listy jest string!
		positionA = positionA.toString();
		positionB = positionB.toString();

		var order = WFormManager.getOrder();
		var keyA = order.indexOf(positionA.toString());
		var keyB = order.indexOf(positionB.toString());
		
		console.log(keyA,keyB);
		return keyA - keyB;

		if (keyA > keyB) {
			console.log('>');
			
		} else
		if (keyA < keyB) {
			console.log('>');
			return -1;
		}

		console.log('=');
		return 0;
	},
	
	toString: function(el) {
		for(var i = 0; i < this.elements.length; i++) {
			var li = $('<li>')
				.addClass('form-element-used')
				.attr('id',i)
				.html(this.elements[i].toString())
				.dblclick(function(){
					WFormManager.removeElementByPosition($(this).attr('id'));
					$('#forms-constructor').html('');
					WFormManager.toString($('#forms-constructor'));
					li.remove();
				});
			el.append(li);
		}
	},

	toObject: function() {
		console.log('ilosc elementów:' + this.elements.length);

		var obj = {elements:{}};

		// sortujemy
		var elements = this.elements.sort(this._orderAlgorithm);
		for(var i = 0; i < elements.length; i++) {
			var el = elements[i];
			el.setOrder(i);
			obj.elements[el.getName()] = el.toObject();
		}

		return obj;
	},
	
	addElement: function(element) {
		if (typeof element == 'object') {
			this.elements.push(element);
		} else {
			console.log('WFormManager::addElement type');
		}
	},

	removeElementByPosition: function(position) {
		var newElements = [];
		for(var i = 0; i < this.elements.length; i++) {
			if (i != position) {
				newElements.push(this.elements[i]);
			}
		}

		this.elements = newElements;
	},

	createElement: function(elementJOSN) {
		var element = clone(WFormElement);

		element.setOptions(elementJOSN.options);
		element.setType(elementJOSN.type);
		element.setName(elementJOSN.name);
		element.setPreview($('[elementType='+elementJOSN.type+']').clone());

		return element;
	},

	getElements: function() {
		return this.elements;
	},

	setup: function(formJSON) {
		this.clear();

		if (typeof formJSON != 'object') {
			console.log('WFormManager::setup no typeof object');
			return;
		}
		if (typeof formJSON.elements != 'object') {
			console.log('WFormManager::setup no typeof array');
			return;
		}

		var self = this;
		$.each(formJSON.elements, function(i,elementJSON){
			var element 	= self.createElement(elementJSON);
			self.addElement(element);
		});
	}
};

$(function() {
	// akcjie draggable
	$(".form-element")
		.dblclick(function(){
			addElement(this);
		})
		.draggable({
			helper: 'clone',
			revert: true
		});

	var formConstructor = $('#forms-constructor').sortable({
		forcePlaceholderSize: true,
		update: function(e, ui){
			WFormManager.setOrder($(this).sortable('toArray'));
		}
	});

	function addElement(elementEl) {
		// pobieramy typ elementu
		var type = $(elementEl).attr('elementType');

		if (WFormElement.isTypeValid(type)) {
			var element = clone(WFormElement);
			element.setType(type);

			element.setPreview($(elementEl).clone());

			WFormManager.addElement(element);

			formConstructor.html('');
			WFormManager.toString(formConstructor);
			formConstructor
				.sortable("refresh");
	 	} else {
	 		console.log("incorrect type added!");
		}
	}

	// akcje droppable
	$("#forms-constructor-droppable").droppable({
		accept: '.form-element',
		activeClass : 'ui-droppable-acticve-class',
		drop: function (e, ui) {
			addElement(ui.draggable);
		}
	});

	$("#forms-constructor-trash").droppable({
		accept: '.form-element-used',
		activeClass : 'ui-droppable-acticve-class',
		drop: function (e, ui) {
			var el = $(ui.draggable);
			console.log('delete element :',el.attr('id'));
			WFormManager.removeElementByPosition(el.attr('id'));
			el.remove();
		}
	});

	$('#form-clear').click(function(){
		WFormManager.clear();
		formConstructor.html('');
		return false;
	});

	$('#form-load').click(function(){

		$.ajax({
			url:'forms/constructor/list/format/json',
			dataType: 'json',
			success: function(json) {
				if (typeof json.rowset == 'object') {
					var div = $('<div/>');
					var ul = $('<ul/>');

					for(var i = 0; i < json.rowset.length; i++) {
						var name = json.rowset[i];
						var li = $('<li/>');
						var loadLink = $('<a/>')
								.attr('id', name)
								.text(name + ' [wczytaj]')
								.attr('href','forms/constructor/load/form/'+ name +'/format/json')
								.click(function(){
									$.ajax({
										url: this.href,
										dataType: 'json',
										success: function(json) {
											// ustawienie danych dla formularza zapisu!
											var saveDialogEl = $('#dialog-save');
											saveDialogEl.find('input[name=subject]').val(json.options.subject);
											saveDialogEl.find('input[name=emailName]').val(json.options.emailName);
											saveDialogEl.find('input[name=name]').val(json.options.name);
											saveDialogEl.find('input[name=email]').val(json.options.email);

											// i generujemy formularz!
											WFormManager.setup(json.form);

											formConstructor.html('');
											WFormManager.toString(formConstructor);
											formConstructor
												.sortable("refresh");
										}
									});
									return false;
								});
						li.append(loadLink);

						li.append(' | ');
						
						var deleteLink = $('<a/>')
								.text('[usuń]')
								.attr('href','forms/constructor/delete/form/'+ name +'/format/json')
								.click(function(){
									if (confirm("Czy chcesz usunąć formularz?")) {
										$.ajax({
											url: this.href,
											dataType: 'json',
											success: function(json) {
												if (json.success == true) {
													deleteLink.parent('li').remove();
													alert("Formularz usunięty");
												} else {
													alert("Formularz NIE został usunięty!");
												}
											}
										});
									}
									return false;
								})
						li.append(deleteLink);
						ul.append(li);
					}
					div.html(ul);

					div.dialog({
						width: '300px',
						height: '300px',
						modal: true,
						title: 'Wczytaj formularz'
					});
				} else {
					alert("Błąd podczaw wczytywania");
				}
			}
		});
		return false;
	});
	
	var saveDialogEl = $('#dialog-save');
	$('#form-save').click(function(){
		saveDialogEl
		.show()
		.dialog({
			width: '470px',
			height: '340px',
			modal: true,
			title: 'Zapisz formularz',
			buttons: { 
		        "Zapisz": function() {

	        		var self = this;
					$.ajax({
						url:'forms/constructor/add/format/json',
						type: 'post',
						dataType: 'json',
						data: build_http_query({
							form : WFormManager.toObject(),
							options : {
								subject: (saveDialogEl.find('input[name=subject]').val()),
								emailName: (saveDialogEl.find('input[name=emailName]').val()),
								name: (saveDialogEl.find('input[name=name]').val()),
								email: (saveDialogEl.find('input[name=email]').val())
							}
						}),
						success: function(data) {
							if (data.success != true) {
								alert('Nie zapisano formularza!: ' + data.messages.join("\n"));
							} else {
								$(self).dialog("close"); 
							}
						}
					});
		        },
		        "Anuluj": function() { 
		            $(this).dialog("close"); 
		        } 
		}
		});
	});

	$('#form-preview').click(function(){
		$.ajax({
			url:'forms/constructor/preview/format/html',
			type: 'post',
			data: build_http_query(WFormManager.toObject()),
			dataType: 'html',
			success: function(data){
				$('<div/>')
					.html(data)
					.dialog({
						width: '600px',
						height: '400px',
						modal: true,
						title: 'Podgląd'
					});
			}
		});
	});

	$('#form-preview-ini').click(function(){
		$.ajax({
			url:'forms/constructor/preview/format/ini',
			type: 'post',
			data: build_http_query(WFormManager.toObject()),
			dataType: 'html',
			success: function(data){
				$('<div/>')
					.html(data)
					.dialog({
						width: '600px',
						height: '200px',
						modal: true,
						title: 'Podgląd'
					});
			}
		});
	});
});
//-->
</script>

<div class="span-17 colborder">
	<div class="options-holder">
		<h3>Blok konstrukcyjny</h3>
		<ul class="options-list top-right">
			<li><input type="button" id="form-save" value="Zapisz"></li>
			<li><input type="button" id="form-load" value="Wczytaj"></li>
			<li><input type="button" id="form-preview" value="Podgląd"></li>
			<li><input type="button" id="form-preview-ini" value="Wygereruj INI"></li>
			<li><input type="button" id="form-clear" value="Wyczyść"></li>
		</ul>
	</div>

	<hr/>

	<div class="span-10">
		<p id="forms-constructor-droppable" class="form-block">W tym miejsciu upuść element formularza</p>
	</div>
	<div class="span-7 last">
		<p id="forms-constructor-trash" class="form-block">Kosz</p>
	</div>
	
	<hr/>

	<div class="form-block">
		<ul id="forms-constructor" class="zend_form" />
	</div>
</div>

<div class="span-4 last">
	<h3>Przybornik</h3>
	<div id="forms-types">
		<div class="form-element form-block" elementType="text">
			<input class="width-fluid"/>
		</div>
		<div class="form-element form-block" elementType="textarea">
			<textarea class="width-fluid"></textarea>
		</div>
		<div class="form-element form-block" elementType="checkbox">
			<input type="checkbox" />
		</div>
		<div class="form-element form-block" elementType="radio">
			<input type="radio" />
		</div>
		<div class="form-element form-block" elementType="reset">
			<input type="reset" />
		</div>
		<div class="form-element form-block" elementType="submit">
			<input type="submit" />
		</div>
	</div>
</div>

<div id="dialog-save" style="display: none;">
<form method="post" action="" enctype="application/x-www-form-urlencoded">
<dl class="zend_form">
	<dt><label class="optional" for="subject">Temat formularza</label></dt>
	<dd>
		<input type="text" value="" id="subject" name="subject"/>
	</dd>
	<dt><label class="optional" for="name">Nazwa formularza</label></dt>
	<dd>
		<input type="text" value="" id="name" name="name"/>
		<p class="description">Powinna być unikalna</p>
	</dd>
	<dt><label class="optional" for="email">Adres email</label></dt>
	<dd>
		<input type="text" value="" id="email" name="email"/>
		<p class="description">Adres email, na który zostanie wysłany dormularz</p>
	</dd>
	<dt><label class="optional" for="emailName">Nazwa nadawcy</label></dt>
	<dd>
		<input type="text" value="" id="emailName" name="emailName"/>
	</dd>
</dl>
</form>
</div>
